import Menu from '@/structure/menu';
import NotFound from '@/views/404.vue';
import Empty from '@/views/empty.vue';
import Root from '@/views/root.vue';
import {RouteConfig} from 'vue-router';
import {Component} from 'vue-router/types/router';

const PREFIX = process.env.VUE_APP_COOKIE_PREFIX;
/**
 * 404定义
 */
const NOT_FOUND = {
  path: '*',
  name: '404',
  component: NotFound,
  meta: {
    hidden: true
  }
} as RouteConfig;

function setItem(key: string, value: any): void {
  localStorage.setItem(PREFIX + key, value);
}

function getItem(key: string): string | null {
  return localStorage.getItem(PREFIX + key);
}

function removeItem(key: string): void {
  localStorage.removeItem(PREFIX + key);
}

/**
 * 构造菜单
 * @param routers vue router列表
 * @param data 菜单列表
 */
function generaMenu(routers: RouteConfig[], data: Menu[]): void {
  data.forEach((item) => {
    const menu = {
      path: item.path,
      name: item.menuKey,
      children: []
    } as RouteConfig;

    if (item.redirect) {
      menu.redirect = item.path;
    } else {
      menu.component = lazyLoading(item);
    }

    if (item.children && item.children.length > 0) {
      menu.children = [];

      generaMenu(menu.children, item.children);
    }

    menu.meta = Object.assign({}, item);

    routers.push(menu);
  });
}

/**
 * 加载菜单
 * @param componentPath 组件路径
 * @param module 模块名
 */
function lazyLoading({componentPath, module}: Menu): Component {
  if (componentPath.toLowerCase() === 'root') {
    return Root;
  } else if (componentPath.toLowerCase() === 'empty') {
    return Empty;
  }

  if (module) {
    return () => import (`@/modules/${module}/views/${componentPath}.vue`);
  } else {
    return () => import (`@/views/${componentPath}.vue`);
  }

}

/**
 * 菜单工具类
 */
class MenuUtils {
  /**
   * 保存菜单列表
   * @param menus 菜单列表
   */
  public static set(menus: Menu[]): void {
    setItem('menus', JSON.stringify(menus));
  }

  /**
   * 清除当前缓存的菜单信息
   */
  public static clean(): void {
    removeItem('menus');
  }

  /**
   * 获取菜单列表
   * @return 菜单列表
   */
  public static get(): Menu[] {
    const data = MenuUtils.parseArray('menus');
    return (Array.isArray(data) ? data : []) as Menu[];
  }

  /**
   * 格式化菜单
   * @param routers vue router列表
   * @param data 菜单列表
   */
  public static format(routers: RouteConfig[], data: Menu[]): void {
    generaMenu(routers, data);
    routers.push(NOT_FOUND);
  }

  private static parseArray(key: string): object {
    let data = getItem(key);
    data = (data === undefined || data === null) ? '[]' : data;
    return JSON.parse(data);
  }
}

export default MenuUtils;
